package com.ruicar.afs.cloud.account.common.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.account.common.dto.AccountVoucherInfoDto;
import com.ruicar.afs.cloud.account.common.entity.VoucherFlowInfo;
import com.ruicar.afs.cloud.account.common.mapper.VoucherFlowInfoMapper;
import com.ruicar.afs.cloud.account.common.service.AccountVoucherEntryService;
import com.ruicar.afs.cloud.account.common.service.AccountVoucherInfoService;
import com.ruicar.afs.cloud.account.common.service.VoucherFlowInfoService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.modules.contract.enums.VoucherSendStatus;
import com.ruicar.afs.cloud.common.modules.contract.enums.VoucherStatusEnum;
import com.ruicar.afs.cloud.common.modules.dto.mq.voucher.VoucherFlowInfoDto;
import com.ruicar.afs.cloud.common.vo.VoucherFlowInfoVo;
import com.ruicar.afs.cloud.voucher.dto.VoucherSendInfoDto;
import com.ruicar.afs.cloud.voucher.feign.VoucherApiFeign;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.MessageFormat;
import java.util.List;

/**
 * @author infinity
 * @version 1.0
 * @date 2020/6/19 20:10
 */
@Service
@Slf4j
@AllArgsConstructor
public class VoucherFlowInfoServiceImpl extends ServiceImpl<VoucherFlowInfoMapper, VoucherFlowInfo> implements VoucherFlowInfoService {
    private final VoucherApiFeign voucherApiFeign;
    private final AccountVoucherInfoService accountVoucherInfoService;
    private final AccountVoucherEntryService accountVoucherEntryService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean checkAndSaveFlow(VoucherFlowInfoDto voucherFlowInfoDto) {
        log.info("保存凭证信息，流水号：[{}],埋点编号：[{}]", voucherFlowInfoDto.getTransNo(), voucherFlowInfoDto.getBuriedPointNo());
        VoucherFlowInfo oldVoucherFlowInfo = this.getOne(Wrappers.<VoucherFlowInfo>lambdaQuery().eq(VoucherFlowInfo::getTransNo, voucherFlowInfoDto.getTransNo()).eq(VoucherFlowInfo::getBuriedPointNo, voucherFlowInfoDto.getBuriedPointNo()), false);
        //相同埋点编号的流水编号已存在
        if (oldVoucherFlowInfo != null) {
            return Boolean.TRUE;
        }
        VoucherFlowInfo voucherFlowInfo = VoucherFlowInfo.convertFromDto(voucherFlowInfoDto);
        return this.save(voucherFlowInfo);
    }

    public JSONObject send(List<VoucherSendInfoDto> list) {
        return voucherApiFeign.send(list);
    }

    //凭证流水结果处理
    @Transactional(rollbackFor = Exception.class)
    public void handleFlowingStatus(List<AccountVoucherInfoDto> dtos, VoucherFlowInfoVo voucherFlowInfo) {
        dtos.stream().forEach(accountVoucherInfoDto -> {
            accountVoucherInfoService.save(accountVoucherInfoDto.getAccountVoucherInfo());
            accountVoucherEntryService.saveBatch(accountVoucherInfoDto.getEntryList());
        });
        Boolean flag = this.update(Wrappers.<VoucherFlowInfo>lambdaUpdate().eq(VoucherFlowInfo::getBuriedPointNo, voucherFlowInfo.getBuriedPointNo())
                .eq(VoucherFlowInfo::getTransNo, voucherFlowInfo.getTransNo()).eq(VoucherFlowInfo::getStatus, VoucherStatusEnum.NOT_CREATED).set(VoucherFlowInfo::getStatus, VoucherStatusEnum.CREATED));
        if (!flag) {
            log.error(MessageFormat.format("业务流水编号：[{0}]状态不是未创建，不可生成凭证底表", voucherFlowInfo.getTransNo()));
        }
        Assert.isTrue(flag, MessageFormat.format("业务流水编号：[{0}]状态不是未创建，不可生成凭证底表", voucherFlowInfo.getTransNo()));
    }

    @Override
    public void handleFlowingErrMsg(Long id,String errMsg) {
        this.update(Wrappers.<VoucherFlowInfo>lambdaUpdate().eq(VoucherFlowInfo::getId, id)
                .eq(VoucherFlowInfo::getStatus, VoucherStatusEnum.NOT_CREATED).set(VoucherFlowInfo::getStatus, VoucherStatusEnum.FAIL_CREATED).set(VoucherFlowInfo::getErrMsg, errMsg));
    }

    @Override
    public Boolean resetFlowStatus(long id) {
        VoucherFlowInfo info = this.getById(id);
        Assert.isTrue(info != null, "凭证流水不存在！");
        Assert.isTrue(VoucherStatusEnum.FAIL_CREATED.equals(info.getStatus()), MessageFormat.format("凭证状态不为：{0},凭证流水信息不可重置!", AfsEnumUtil.desc(VoucherStatusEnum.FAIL_CREATED)));
        return  this.update(Wrappers.<VoucherFlowInfo>lambdaUpdate().eq(VoucherFlowInfo::getId, id)
                .eq(VoucherFlowInfo::getStatus, VoucherStatusEnum.FAIL_CREATED).set(VoucherFlowInfo::getStatus, VoucherStatusEnum.NOT_CREATED));
    }

    @Override
    public Boolean resetItemStatus(long id) {
        VoucherFlowInfo info = this.getById(id);
        Assert.isTrue(info != null, "凭证流水不存在！");
        Assert.isTrue(VoucherSendStatus.SEND_FAIL.equals(info.getItemStatus()), MessageFormat.format("凭证状态不为：{0},凭证流水信息不可重置!", AfsEnumUtil.desc(VoucherSendStatus.SEND_FAIL)));
        return this.update(Wrappers.<VoucherFlowInfo>lambdaUpdate().eq(VoucherFlowInfo::getId, id)
                .eq(VoucherFlowInfo::getItemStatus, VoucherSendStatus.SEND_FAIL).set(VoucherFlowInfo::getStatus, VoucherSendStatus.NOT_SEND));
    }
}
